/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package it.lapomuge.db.dao;

import it.lapomuge.db.entity.Gara;
import it.lapomuge.db.entity.Giudice;
import it.lapomuge.db.entity.Partecipazione;

import java.lang.reflect.Array;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.Query;

/**
 * 
 * @author Muge
 */
public class DbManager {

	private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("ScoreAppPU");

	protected DbManager() {
	}

	public static DbManager getInstance() {
		return new DbManager();
	}

	protected EntityManager getEntityManager() {
		return emf.createEntityManager();
	}

	public<T extends DbEntity>  void delete(Class<T> class1, T... array) {
		EntityManager em = this.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		for (T i : array) {
			
			em.remove(em.merge(i));			
		}
		tx.commit();
		em.close();
	}

	public <T extends DbEntity> void save(Class<T> classe, T... object) {
		EntityManager em = this.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		this.save(classe, em, object);
		tx.commit();
		em.close();
	}

	public <T extends DbEntity> void save(Class<T> classe, EntityManager em, T... object) {

		Integer max = this.getMaxId(em, classe);
		for (T t : object) {
			if (t.getId() == null) {

				t.setId(max++);
				em.persist(t);

			} else {
				em.persist(em.merge(t));
			}

		}

	}

	public <T extends DbEntity> Integer getMaxId(EntityManager em, Class<T> classe) {

		Entity an = classe.getAnnotation(Entity.class);
		Query q = null;
		if (an.name() == null || an.name().trim().equals("")) {
			q = em.createQuery("select max(c.id) from " + classe.getSimpleName() + " c");
		} else {
			q = em.createQuery("select max(c.id) from " + an.name() + " c");
		}
		try {
			Integer max = (Integer) q.getSingleResult();
			return max == null ? 0 : max + 1;
		} catch (NoResultException ex) {
			return 0;
		}

	}

	public <T extends DbEntity> T findById(Class<T> classe, Integer id) {
		EntityManager em = this.getEntityManager();
		Entity an = classe.getAnnotation(Entity.class);
		Query q = null;
		if (an.name() == null || an.name().trim().equals("")) {
			q = em.createQuery("select c from " + classe.getSimpleName() + " c where c.id = :id");
		} else {
			q = em.createQuery("select c from " + an.name() + " c where c.id = :id");
		}
		try {
			q.setParameter("id", id);

			return (T) q.getSingleResult();
		} catch (NoResultException ex) {
			return null;
		} finally {
			em.close();
		}

	}

	public <T> T[] findAll(Class<T> classe) {
		EntityManager em = this.getEntityManager();
		Entity an = classe.getAnnotation(Entity.class);
		Query q = null;
		if (an.name() == null || an.name().trim().equals("")) {
			q = em.createQuery("select c from " + classe.getSimpleName() + " c");
		} else {
			q = em.createQuery("select c from " + an.name() + " c");
		}
		try {

			List list = q.getResultList();
			return (T[]) list.toArray((T[]) Array.newInstance(classe, list.size()));
		} catch (NoResultException ex) {
			return (T[]) Array.newInstance(classe, 0);
		} finally {
			em.close();
		}

	}

	public String getTableName(Class classe) {
		Entity an = (Entity) classe.getAnnotation(Entity.class);
		if (an.name() == null || an.name().trim().equals("")) {
			return classe.getSimpleName();
		} else {
			return an.name();
		}
	}

	public static void main(String[] args) {
		Giudice g = new Giudice();
		g.setNome("Prova");
		g.setCognome("pr");
		g.setLogin("s");
		g.setPassword("ssdf");

		new DbManager().save(Giudice.class, g);

		System.out.println(g.getId());

		Gara[] findAll = new DbManager().findAll(Gara.class);
		for (Gara gara : findAll) {
			System.out.println("Prova");
			gara.setNome("BOOHOHOHO");
			new DbManager().save(Gara.class, gara);

		}

	}

}
